package com.nbsaas.boot.controller.store;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.nbsaas.boot.config.ext.apis.ConfigExtApi;
import com.nbsaas.boot.resource.OssResource;
import com.nbsaas.boot.rest.response.MapResponse;
import com.nbsaas.boot.rest.response.ResponseObject;
import com.nbsaas.boot.security.utils.SubjectUtils;
import com.nbsaas.boot.storage.api.apis.FileApi;
import com.nbsaas.boot.storage.api.domain.request.FileRequest;
import com.nbsaas.boot.storage.ext.domain.config.AliOssConfig;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;

@RequestMapping("/oss")
@RestController
public class AliFileController {


    @Resource
    private ConfigExtApi configExtApi;


    @Resource
    private OssResource ossResource;

    @Resource
    private FileApi fileApi;

    @RequiresAuthentication
    //@Transactional
    @PostMapping("/upload")
    @ResponseBody
    public ResponseObject<MapResponse> upload(@RequestParam("file") MultipartFile file) {
        return uploadFile(file, true);
    }


    @RequiresAuthentication
    @PostMapping("/uploadSimple")
    @ResponseBody
    public ResponseObject<MapResponse> uploadSimple(@RequestParam("file") MultipartFile file) {
        return uploadFile(file, false);
    }

    private ResponseObject<MapResponse> uploadFile(MultipartFile file, boolean randomName) {
        ResponseObject<MapResponse> result = new ResponseObject<>();

        // 检查文件是否为空  @RequestParam("file")
        if (file.isEmpty()) {
            result.setCode(501);
            result.setMsg("请选择一个文件进行上传");
            return result;
        }
        ResponseObject<AliOssConfig> res = configExtApi.info(AliOssConfig.class);
        if (res.getCode() != 200) {
            result.setCode(502);
            result.setMsg("你没有配置上传信息");
            return result;
        }
        AliOssConfig config = res.getData();
        OSS ossClient = new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
        String folder = config.getFolder();
        if (!StringUtils.hasText(folder)) {
            folder = "files";
        }
        if (!folder.endsWith("/")) {
            folder = folder + "/";
        }

        try {
            String fileName = file.getOriginalFilename();

            // 获取文件后缀
            String fileExtension = StringUtils.getFilenameExtension(fileName);

            String urlName = fileName;

            if (randomName) {
                urlName = UUID.randomUUID().toString().replace("-", "") + "." + fileExtension;
            }
            String key = folder + urlName;

            ObjectMetadata meta = new ObjectMetadata();
            meta.setContentType(file.getContentType());
            ossClient.putObject(config.getBucketName(), key, file.getInputStream(), meta);


            MapResponse mapResponse = new MapResponse();
            mapResponse.put("url", ossResource.url(key).getData());

            mapResponse.put("path", key);
            result.setData(mapResponse);

            result.setData(mapResponse);

            FileRequest req = new FileRequest();
            req.setFileType(1);
            req.setFileSize(file.getSize());
            req.setExtensionName(fileExtension);
            req.setName(fileName);
            req.setServerUrl(config.getDomain());
            req.setObjectKey(key);
            req.setCreatorId(SubjectUtils.user().getId());
            req.setCreatorName(SubjectUtils.user().getName());
            req.setAddDate(new Date());
            req.setLastDate(new Date());
            req.setTenantId(SubjectUtils.user().getTenantId());
            fileApi.create(req);
        } catch (Throwable e) {
            e.printStackTrace();
            result.setCode(501);
            result.setMsg("上传文件失败");
        } finally {
            ossClient.shutdown();
        }
        return result;
    }

}
